#include "matrix.hpp"
#include<bits/stdc++.h>
using namespace std;

matrix <double> A, B, C, D;
rowvec <double> u, v;
colvec <double> x, y;

void Test1(){
	cout << "Test 1: Creating a Matrix" << endl;
	
	int n1,m1,n2,m2;
	
	cin >> n1 >> m1;
	try{
		A = matrix <double> (n1, m1);
		A.read();
		cout << "A =" << endl;
		A.write();
	}
	catch (const char* msg){
		cout << msg << endl, exit(-1);
	}
	
	cin >> n2 >> m2;
	try{
		B = matrix <double> (n2, m2);
		B.read();
		cout << "B =" << endl;
		B.write();
	}
	catch (const char* msg){
		cout << msg << endl, exit(-1);
	}
}

void Test2(){
	cout << "Test 2: Is_square" << endl;
	cout << (A.issq() ? "A is a square" : "A is not a square") <<endl;
}

void Test3(){
	cout << "Test 3: Addition and Subtract of Matrices" << endl;
	try{
		C = A + B;
		cout << "A + B =" << endl;
		C.write();
	}
	catch (const char* msg){
		cout << msg << endl;
	}
	
	try{
		D = A - B;
		cout << "A - B =" << endl;
		D.write();
	}
	catch (const char* msg){
		cout << msg << endl;
	}
}

void Test4(){
	cout << "Test 4: Multiply of Matrices" << endl;
	try{
		C = A * B;
		cout << "A * B =" << endl;
		C.write();
	}
	catch (const char* msg){
		cout << msg << endl;
	}
}

void Test5(){
	cout << "Test 5: Creating a Row Vector and a Col Vector" << endl;
	
	int n1, n2, m1, m2;
	
	cin >> n1;
	try{
		u=rowvec <double> (n1);
		u.read();
		cout << "u =" << endl;
		u.write();
	}
	catch (const char* msg){
		cout << msg << endl,exit(-2);
	}
	
	cin >> n2;
	try{
		v = rowvec <double> (n2);
		v.read();
		cout << "v =" << endl;
		v.write();
	}
	catch (const char* msg){
		cout << msg << endl,exit(-2);
	}
	
	cin >> m1;
	try{
		x = colvec <double> (m1);
		x.read();
		cout << "x =" << endl;
		x.write();
	}
	catch (const char* msg){
		cout << msg << endl,exit(-2);
	}
	
	cin >> m2;
	try{
		y = colvec <double> (m2);
		y.read();
		cout << "y =" << endl;
		y.write();
	}
	catch (const char* msg){
		cout << msg << endl,exit(-2);
	}
}

void Test6(){
	cout << "Test 6: Multiply of Vectors" << endl;
	double r;
	matrix <double> H;
	
	try{
		r = u * x;
		cout << "u * x = " << r << endl;
	}
	catch (const char* msg){
		cout << msg << endl;
	}
	
	try{
		r = u * v;
		cout << "u . v = " << r << endl;
	}
	catch (const char* msg){
		cout << msg << endl;
	}
	
	try{
		r = x * y;
		cout << "x . y = " << r << endl;
	}
	catch (const char* msg){
		cout << msg << endl;
	}
	
	try{
		H = x * u;
		cout << "x * u = " <<endl;
		H.write();
	}
	catch (const char* msg){
		cout << msg << endl;
	}
}

void Test7(){
	cout << "Test 7: Determinent" << endl;
	double r;
	try{
		r = A.det();
		cout << "det(A) = " << r << endl;
	}
	catch (const char* msg){
		cout << msg << endl;
	}
}

void Test8(){
	cout << "Test 8: Inverse" << endl;
	try{
		C = A.inv();
		cout << "A^-1 = " << endl;
		C.write();
	}
	catch (const char* msg){
		cout << msg << endl;
	}
}

int main(){
	cout << "Test begin." << endl;
	Test1();
	Test2();
	Test3();
	Test4();
	Test5();
	Test6();
	Test7();
	Test8();
}
